package ema.tpjee.banking.controler;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ema.tpjee.banking.dao.BankDao;
import ema.tpjee.banking.dao.CustomerDao;
import ema.tpjee.banking.model.Bank;
import ema.tpjee.banking.model.Customer;
import ema.tpjee.banking.session.BankingSession;
import ema.tpjee.utils.AppLocator;
import ema.tpjee.utils.ServletUtils;

/**
 * Servlet implementation class for Servlet: BankControler
 * les dao sont dï¿½tenus par les servlets, ils sont partagï¿½s pas toutes les sessions, ils sont stateless
 * 
 * 
 */
public class BankControler extends javax.servlet.http.HttpServlet implements
		javax.servlet.Servlet {
	static final long serialVersionUID = 1L;

	

	/**
	 * reconstituer le nouvel objet ï¿½ partir des paramï¿½tres de la request les
	 * frameworks le font par introspection
	 * 
	 * @param request
	 * @return
	 */
	private Bank formValue(HttpServletRequest request) {
		if (request.getParameter("id") == null)
			return null;
		Bank result = new Bank();
	
		int rid = Integer.parseInt(request.getParameter("id"));
		result.setId(rid);
		
		result.setName(request.getParameter("name"));
		result.setAddress(request.getParameter("address"));
		result.setPhone(request.getParameter("phone"));
		try {
			result.setZipCode(request.getParameter("zipCode"));
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * validation x On souhaiterait une hiï¿½rarchie d'exceptions
	 * 
	 * @param b
	 */
	private void validate(Bank b) {
		if (b.getName().contains("supercrash")
				|| b.getName().contains("forbidden"))
			throw new RuntimeException("the name is forbidden!");
	}

	/**
	 * validation y On souhaiterait une hiï¿½rarchie d'exceptions
	 * 
	 * @param b
	 */
	private void validateFoobar(Bank b) {
		if (Integer.parseInt(b.getZipCode()) > 150000)
			throw new RuntimeException("foobar is too big!");
	}

	/**
	 * modifier l'objet au sein du modï¿½le aprï¿½s validation
	 * 
	 * @param request
	 * @param b
	 * @return
	 */
	private Bank doModify(HttpServletRequest request, BankingSession session, Bank b) {
		Bank result = null;
		try {
			validate(b);
			result = session.getBankDao().merge(b); 
			// le modï¿½le est mis ï¿½ jour, si pas d'exception
		} catch (Exception e) {
			result = b; 
			// formBean is returned but not modified in persistence layer
			System.out.println("error " + e.getMessage());
			request.setAttribute("error", "erreur " + e.getMessage());
		}
		return result;
	}

	/**
	 * foobar est une action mï¿½tier (autre qu'une simple opï¿½ration CRUD) exemple
	 * d'une contrainte susceptible de lever une exception sï¿½mantique, pour
	 * tester les mï¿½canismes de validation
	 * 
	 * A noter: Adhï¿½rence de la couche mï¿½tier avec la couche web (paramï¿½tre
	 * request) On souhaiterait un mï¿½canisme gï¿½nï¿½rique de gestion d'erreurs
	 * 
	 * @param request
	 * @param b
	 *            the bank to foobar
	 * @return the foobared bank
	 */
	private Bank foobar(HttpServletRequest request, BankingSession session,Bank b) {
		Bank result = null;
		int foobar = 0;
		try {
			Collection<Bank> bks = session.getBankDao().getList();
			for (Iterator<Bank> i = bks.iterator(); i.hasNext();) {
				Bank bb = i.next();
				foobar += Integer.parseInt(bb.getZipCode());
			}
			b.setZipCode(Integer.toString(foobar));
			result = session.getBankDao().foobar(b); 
			// la RG peut ï¿½tre dï¿½lï¿½guï¿½e au composant
			validateFoobar(b); 
			// la RG peut ï¿½tre vï¿½rifiï¿½e par le contrï¿½leur
			result = session.getBankDao().merge(b); 
			// si pas d'exception, le modï¿½le est mis ï¿½ jour
		} catch (Exception e) {
			result = b; 
			// formBean is returned but not modified in persistence layer
			System.out.println("error " + e.getMessage());
			request.setAttribute("error", "erreur " + e.getMessage());
		}
		return result;
	}

	/**
	 * Mï¿½thode recevant l'action en provednance du client On souhaiterait
	 * gï¿½nï¿½raliser le mï¿½canisme Cette gï¿½nï¿½ralisation est rï¿½alisï¿½e par les
	 * frameworks (struts, spring, etc..) et par JSF
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		BankingSession bsession = (BankingSession) request.getSession().getAttribute("sessionbean");
		if (bsession==null){
			getServletContext().getRequestDispatcher("/nosession.jsp").forward(request, response);
			return;
		}		
		
		ServletUtils.debugRequestParameters(this.getClass(), request);
		ServletUtils.debugSessionAttributes(this.getClass(), request);

		// ï¿½tape 1 dï¿½coder les ï¿½vï¿½nements depuis la request

		String page_ = request.getParameter("page");
		String cmd = request.getParameter("cmd");
		
		String  formbeanclassname = request.getParameter("formbeanclass");

		System.out.println("cmd = " + cmd);

		// ï¿½tape 2 reconstituer l'objet de domaine depuis la request

		Bank oldBean = null; 
		// l'ancienne valeur
		Bank newBean = null; 
		// la nouvelle valeur, celle qui sera prï¿½sentï¿½e ï¿½ la vue
		Bank formBean = null;
		
	
		if (Bank.class.getName().equals(formbeanclassname)) 
			formBean = formValue(request); 
		
		
		
		// la valeur reï¿½ue par la requï¿½te (avant validation)

		// ï¿½tape 3 retrouver la valeur de l'objet du domaine avant l'action

		if (formBean != null)
			oldBean = bsession.getBankDao().find(formBean.getId()); 
		// de prï¿½fï¿½rence dans la couche de persistance
		else
			oldBean = (Bank) request.getSession().getAttribute("currentbank");
		// sinon dans notre contexte web

		if (oldBean == null)
			oldBean = bsession.getBankDao().first(); 
		// par dï¿½faut, prendre le premier de la liste

		// ï¿½tape 4
		// 4a appliquer les RG
		// 4b gï¿½rer les erreurs de validation, gï¿½nï¿½rer les messages d'erreur
		// 4c appliquer la nouvelle valeur sur le modï¿½le si ok
		// 4d prï¿½parer l'objet validï¿½ et modifiï¿½ ou invalidï¿½ pour correction, ï¿½
		// prï¿½senter dans la vue (newbean)

		if ("editer".equals(cmd))
			newBean = oldBean;
		else if ("suivant".equals(cmd))
			newBean = bsession.getBankDao().next(oldBean);
		else if ("precedent".equals(cmd))
			newBean = bsession.getBankDao().prior(oldBean);
		else if ("dupliquer".equals(cmd))
			newBean = bsession.getBankDao().clone(oldBean);
		else if ("supprimer".equals(cmd))
			newBean = bsession.getBankDao().delete(oldBean);
		else if ("ajouter".equals(cmd))
			newBean = bsession.getBankDao().create();
		else if ("annuler".equals(cmd))
			newBean = oldBean;
		else if ("modifier".equals(cmd))
			newBean = doModify(request, bsession, formBean);
		else if ("foobar".equals(cmd))
			newBean = foobar(request, bsession, formBean);


		if (newBean != null)
			request.getSession().setAttribute("currentbank", newBean); //pour interface avec les jsp
		else
			request.getSession().setAttribute("currentbank", oldBean);
		request.getSession().setAttribute("banks", bsession.getBankDao().getList());// reverseListBank());

		// ï¿½tape 5 appliquer les rï¿½gles de navigation, diriger la requï¿½te vers la vue
		String fw = null;

		if ("clients".equals(cmd))
			fw = "/customer.do"; 
		// les controleurs ne se connaissent pas entre eux. On passe par l'uri. On
		// utilise le contexte de session ou de requï¿½te pour passer les paramï¿½tres
		else if (page_ != null && !"null".equals(page_))
			fw = "/pages/" + page_ + ".jsp";
		else
			fw = "/pages/bank.jsp";

		// ï¿½tape 6 faire suivre l'exï¿½cution vers la vue
		System.out.println("forwarding to: " + fw);
		getServletContext().getRequestDispatcher(fw).forward(request, response);
	}

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}


}